package com.gitee.kamismile.stone.basic.data.domain.sysUser.service.impl;

import com.gitee.kamismile.stone.basic.data.domain.sysUser.repository.entity.*;
import com.gitee.kamismile.stone.basic.data.domain.sysUser.service.ISysUserDomainService;
import com.gitee.kamismile.stone.basic.data.infrastructure.enums.UserErrorEnum;
import com.gitee.kamismile.stone.basic.data.infrastructure.repository.r2Repository.sysUser.repository.*;
import com.gitee.kamismile.stone.basic.data.infrastructure.utils.PageQueryBuilder;
import com.gitee.kamismile.stone.commmon.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

@Service
public class SysUserDomainServiceImpl implements ISysUserDomainService {
    @Autowired
    private R2dbcEntityTemplate template;

    @Autowired
    private SysUserResRepository sysUserResRepository;

    @Autowired
    private SysUserDepRepository sysUserDepRepository;

    @Autowired
    private SysUserRoleRepository sysUserRoleRepository;

    @Autowired
    private SysUserSetupRepository sysUserSetupRepository;

    @Autowired
    private SysUserShortcutRepository sysUserShortcutRepository;



    @Override
    public Mono<SysDepUser> saveOrUpdate(SysDepUser sysDepUser) {
        return sysUserDepRepository.save(sysDepUser);
    }

    @Override
    public Mono<Void> deleteUserDepById(Integer nSysDepUserId) {
        return sysUserDepRepository.deleteById(nSysDepUserId);
    }


    @Override
    public Mono<Void> deleteUserDepByUserId(Integer nUserId, Integer nTenantId) {
        return sysUserDepRepository.deleteUserDepByUserId(nUserId,nTenantId);
    }

    @Override
    public Mono<Page<SysDepUser>> findUserDepPage(int page, int size, Criteria criteria) {
        Pageable pageable = PageRequest.of(page, size);
        return new PageQueryBuilder<>(template, SysDepUser.class)
                .where(criteria)
                .pageable(pageable)
                .apply();
    }

    @Override
    public Mono<SysDepUser> findAndCheckUserDepById(Integer nSysDepUserId, Integer nTenantId) {
        return findUserDepById(nSysDepUserId, nTenantId)
                .switchIfEmpty(Mono.defer(() -> Mono.error(
                        new BusinessException(
                                UserErrorEnum.UserDepNotFound.getCode(),
                                UserErrorEnum.UserDepNotFound.getMessage()
                        ))));
    }

    public Mono<SysDepUser> findUserDepById(Integer nSysDepUserId, Integer nTenantId) {
        Assert.notNull(nSysDepUserId, UserErrorEnum.UserDepNotNull.getMessage());
        SysDepUser example = new SysDepUser();
        example.setnSysDepUserId(nSysDepUserId);
        example.setnTenantId(nTenantId);
        return sysUserDepRepository.findOne(Example.of(example));
    }

    @Override
    public Mono<SysRoleUser> saveOrUpdate(SysRoleUser sysRoleUser) {
        return sysUserRoleRepository.save(sysRoleUser);
    }

    @Override
    public Flux<SysRoleUser> saveBatch(List<SysRoleUser> sysRoleUsers) {
        return sysUserRoleRepository.saveAll(sysRoleUsers);
    }

    @Override
    public Mono<Void> deleteUserRoleById(Integer nSysRoleUserId) {
        return sysUserRoleRepository.deleteById(nSysRoleUserId);
    }

    @Override
    public Mono<Void> deleteUserRoleByUserId(Integer nUserId, Integer nTenantId) {
        return sysUserRoleRepository.deleteUserRoleByUserId(nUserId,nTenantId);
    }

    @Override
    public Mono<Page<SysRoleUser>> findUserRolePage(int page, int size, Criteria criteria) {
        Pageable pageable = PageRequest.of(page, size);
        return new PageQueryBuilder<>(template, SysRoleUser.class)
                .where(criteria)
                .pageable(pageable)
                .apply();
    }

    @Override
    public Mono<SysRoleUser> findAndCheckUserRoleById(Integer nSysRoleUserId, Integer nTenantId) {
          return findUserRoleById(nSysRoleUserId, nTenantId)
                .switchIfEmpty(Mono.defer(() -> Mono.error(
                        new BusinessException(
                                UserErrorEnum.UserRoleNotFound.getCode(),
                                UserErrorEnum.UserRoleNotFound.getMessage()
                        ))));
    }

    public Mono<SysRoleUser> findUserRoleById(Integer nSysRoleUserId, Integer nTenantId) {
        Assert.notNull(nSysRoleUserId, UserErrorEnum.UserRoleNotNull.getMessage());
        SysRoleUser example = new SysRoleUser();
        example.setnSysRoleUserId(nSysRoleUserId);
        example.setnTenantId(nTenantId);
        return sysUserRoleRepository.findOne(Example.of(example));
    }


    @Override
    public Mono<SysUserResources> saveOrUpdate(SysUserResources sysUserResources) {
        return sysUserResRepository.save(sysUserResources);
    }

    @Override
    public Mono<Void> deleteUserResById(Integer nSysUserResourcesId) {
        return sysUserResRepository.deleteById(nSysUserResourcesId);
    }

    @Override
    public Mono<Page<SysUserResources>> findUserResPage(int page, int size, Criteria criteria) {
        Pageable pageable = PageRequest.of(page, size);
        return new PageQueryBuilder<>(template, SysUserResources.class)
                .where(criteria)
                .pageable(pageable)
                .apply();
    }


    @Override
    public Mono<SysUserResources> findAndCheckUserResById(Integer nSysUserResourcesId, Integer nTenantId) {
         return findUserResById(nSysUserResourcesId, nTenantId)
                .switchIfEmpty(Mono.defer(() -> Mono.error(
                        new BusinessException(
                                UserErrorEnum.UserResNotFound.getCode(),
                                UserErrorEnum.UserResNotFound.getMessage()
                        ))));
    }

    public Mono<SysUserResources> findUserResById(Integer nSysUserResourcesId, Integer nTenantId) {
        Assert.notNull(nSysUserResourcesId, UserErrorEnum.UserResNotNull.getMessage());
        SysUserResources example = new SysUserResources();
        example.setnSysUserResourcesId(nSysUserResourcesId);
        example.setnTenantId(nTenantId);
        return sysUserResRepository.findOne(Example.of(example));
    }
    @Override
    public Mono<SysUserSetup> saveOrUpdate(SysUserSetup sysUserSetup) {
        return sysUserSetupRepository.save(sysUserSetup);
    }

    @Override
    public Mono<Void> deleteUserSetupById(Integer nUserSetupId) {
        return sysUserSetupRepository.deleteById(nUserSetupId);
    }

    @Override
    public Mono<Page<SysUserSetup>> findUserSetupPage(int page, int size, Criteria criteria) {
         Pageable pageable = PageRequest.of(page, size);
        return new PageQueryBuilder<>(template, SysUserSetup.class)
                .where(criteria)
                .pageable(pageable)
                .apply();
    }

    @Override
    public Mono<SysUserSetup> findAndCheckUserSetupById(Integer nUserSetupId, Integer nTenantId) {
        return findUserSetupById(nUserSetupId, nTenantId)
                .switchIfEmpty(Mono.defer(() -> Mono.error(
                        new BusinessException(
                                UserErrorEnum.UserSetupNotFound.getCode(),
                                UserErrorEnum.UserSetupNotFound.getMessage()
                        ))));
    }


    public Mono<SysUserSetup> findUserSetupById(Integer nUserSetupId, Integer nTenantId) {
        Assert.notNull(nUserSetupId, UserErrorEnum.UserSetupNotNull.getMessage());
        SysUserSetup example = new SysUserSetup();
        example.setnUserSetupId(nUserSetupId);
        example.setnTenantId(nTenantId);
        return sysUserSetupRepository.findOne(Example.of(example));
    }
    @Override
    public Mono<SysUserShortcut> saveOrUpdate(SysUserShortcut sysUserShortcut) {
        return sysUserShortcutRepository.save(sysUserShortcut);
    }

    @Override
    public Mono<Void> deleteUserShortById(Integer nSysUserShortcutId) {
        return sysUserShortcutRepository.deleteById(nSysUserShortcutId);
    }

    @Override
    public Mono<Page<SysUserShortcut>> findUserShortPage(int page, int size, Criteria criteria) {
          Pageable pageable = PageRequest.of(page, size);
        return new PageQueryBuilder<>(template, SysUserShortcut.class)
                .where(criteria)
                .pageable(pageable)
                .apply();
    }

    @Override
    public Mono<SysUserShortcut> findAndCheckUserShortcutByResId(Integer nResId, Integer nUserId, Integer nTenantId) {
        return findUserShortcutByResId(nResId,nUserId, nTenantId)
                .switchIfEmpty(Mono.defer(() -> Mono.error(
                        new BusinessException(
                                UserErrorEnum.UserShortcutNotFound.getCode(),
                                UserErrorEnum.UserShortcutNotFound.getMessage()
                        ))));
    }


    public Mono<SysUserShortcut> findUserShortcutByResId(Integer nResId, Integer nUserId, Integer nTenantId) {
        Assert.notNull(nResId, UserErrorEnum.UserResNotNull.getMessage());
        SysUserShortcut example = new SysUserShortcut();
        example.setnUserId(nUserId);
        example.setnMenuId(nResId);
        example.setnTenantId(nTenantId);
        return sysUserShortcutRepository.findOne(Example.of(example));
    }

}
